home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / emulator / bsvc-1.000 / bsvc-1 / bsvc-1.0.4 / src / Assemblers / hecasm / asm4.c < prev    next >
C/C++ Source or Header  |  1995-07-26  |  5KB  |  215 lines

  1.  
  2. /*
  3.    File:  asm4.c
  4.    Purpose:  Parse the instruction operands: data operands and branch operands.
  5. */
  6.  
  7. #include "asm.h"
  8.  
  9.  
  10. /*-----------------------------------------------------------------------
  11.    getmode:
  12.    Parse the operand field of an instruction.
  13. */
  14.  
  15. struct d_operand getmode()
  16. {
  17.    int            c;
  18.    char            word[50];
  19.    char            *last_index;
  20.    struct sym        *kp;
  21.    struct d_operand    operand;
  22.  
  23.    operand.parse_error = 0;
  24.    c = getnb();
  25.    switch (c)
  26.    {  case '#':        /* Immediate:                    */
  27.      operand.mode = AM_IP;
  28.      operand.mode_bits = 0x2;
  29.      operand.reg = 15;
  30.      operand.ext_word = expr();
  31.      break;
  32.  
  33.       case '[':        /* Indirect, Indirect w/inc, indexed:        */
  34.      c = getnb();
  35.      getid(c,word);
  36.      kp = pstlookup(word);
  37.  
  38.      /* Symbol not found:                        */
  39.      if ((kp==NULL) || (kp->s_type!=GR_REG))    
  40.      {  err('R',"Expecting register");
  41.         operand.parse_error = 1;
  42.      }
  43.      else
  44.      {  operand.reg = kp->s_value;        /* operating register    */
  45.         c = getnb();
  46.         if (c==']')        /* Indirect:  close braket        */
  47.         {  operand.mode = AM_IN;
  48.            operand.mode_bits = 0x1;
  49.         }
  50.         else if (c=='+')    /* Indirect w/inc:  + sign        */
  51.         {  operand.mode = AM_IP;
  52.            operand.mode_bits = 0x2;
  53.            c = getnb();
  54.            if (c!=']')    /* Closing ]                */
  55.            {  err(']',"brace imbalance");
  56.           operand.parse_error = 1;
  57.            }
  58.         }
  59.         else if (c==',')    /* Indexed:  delimiting comma        */
  60.         {  operand.mode = AM_IX;
  61.            operand.mode_bits = 0x3;
  62.            operand.ext_word = expr();
  63.            c = getnb();
  64.            if (c!=']')    /* Closing ]                */
  65.            {  err(']',"brace imbalance");
  66.           operand.parse_error = 1;
  67.            }
  68.         }
  69.         else        /* Syntax error                */
  70.            operand.parse_error = 1;
  71.      }
  72.      break;
  73.  
  74.       default:        /* Register or PC relative            */
  75.      putback(c);
  76.      last_index = sptr;        /* Remember current char index    */
  77.      c = getnb();
  78.      getid(c,word);
  79.      kp = pstlookup(word);
  80.      if ((kp!=NULL) && (kp->s_type==GR_REG))     /* Register    */
  81.      {  operand.mode = AM_RD;
  82.         operand.mode_bits = 0x0;
  83.         operand.reg = kp->s_value;
  84.      }
  85.      else                        /* PC Relative    */
  86.      /* For PC relative, we should let the caller calc. the actual
  87.            offset.  This avoids offset misalignments.        */
  88.      {  sptr = last_index;
  89.         operand.mode = AM_IX;
  90.         operand.mode_bits = 0x3;
  91.         operand.reg = 15;
  92.         operand.ext_word = expr();        /* Get absolute address    */
  93.      }
  94.      break;
  95.    }/* end switch */
  96.  
  97.    return (operand);
  98. }
  99.  
  100.  
  101. /*
  102.    getbmode:
  103.    Parse the instruction operand field for the branch target.
  104. */
  105. struct d_operand getbmode()
  106. {
  107.    int            c;
  108.    char            word[50];
  109.    char            *last_index;
  110.    struct sym        *kp;
  111.    struct d_operand    operand;
  112.  
  113.    operand.parse_error = 0;
  114.    c = getnb();
  115.    switch (c)
  116.    {  case '@':        /* Absolute                    */
  117.      operand.mode = BM_A;
  118.      operand.mode_bits = 0x1;
  119.      operand.reg = 0;
  120.      operand.ext_word = expr();
  121.      break; 
  122.  
  123.       case '[':        /* Indexed                    */
  124.      operand.mode = BM_I;
  125.      operand.mode_bits = 0x3;
  126.      c = getnb();
  127.      getid(c,word);
  128.      kp = pstlookup(word);
  129.  
  130.      /* Symbol not found:                        */
  131.      if ((kp==NULL) || (kp->s_type!=GR_REG))    
  132.      {  err('R',"Expecting register");
  133.         operand.parse_error = 1;
  134.      }
  135.      else
  136.      {  operand.reg = kp->s_value;        /* operating register    */
  137.         c = getnb();
  138.         if (c==',')        /* Indexed:  delimiting comma        */
  139.         {  operand.ext_word = expr();
  140.            c = getnb();
  141.            if (c!=']')    /* Closing ]                */
  142.            {  err(']',"brace imbalance");
  143.           operand.parse_error = 1;
  144.            }
  145.         }
  146.         else        /* Syntax error                */
  147.         {  err(',',"expecting comma");
  148.            operand.parse_error = 1;
  149.         }
  150.      }
  151.      break;
  152.  
  153.       default:        /* Register or Relative                */
  154.      putback(c);
  155.      last_index = sptr;        /* Remember current char index    */
  156.      c = getnb();
  157.      getid(c,word);
  158.      kp = pstlookup(word);
  159.      if ((kp!=NULL) && (kp->s_type==GR_REG))     /* Register    */
  160.      {  operand.mode = BM_R;
  161.         operand.mode_bits = 0x0;
  162.         operand.reg = kp->s_value;
  163.      }
  164.      else                        /* PC Relative    */
  165.      /* For PC relative, we should let the caller calc. the actual
  166.            offset.  This avoids offset misalignments.        */
  167.      {  sptr = last_index;
  168.         operand.mode = BM_L;
  169.         operand.mode_bits = 0x2;
  170.         operand.reg = 0;
  171.         operand.ext_word = expr();        /* Get absolute address    */
  172.      }
  173.      break;
  174.    }/* end switch */
  175.  
  176.    return (operand);
  177. }
  178.  
  179.  
  180. /*
  181.    getcc:
  182.    Parse the condition codes.
  183. */
  184. struct b_operand getcc()
  185. {
  186.    int            c;
  187.    char            word[50];
  188.    struct sym        *kp;
  189.    struct b_operand    operand;
  190.  
  191.  
  192.    operand.parse_error = 0;
  193.    c = getnb();
  194.    getid(c,word);
  195.    kp = pstlookup(word);
  196.    
  197.    /* Branch condition code not found:                    */
  198.    if ((kp==NULL) || (kp->s_type!=GR_CC))
  199.    {  err('c',"expecting condition code");
  200.       operand.parse_error = 1;
  201.    }
  202.    else
  203.       operand.mode_bits = kp->s_value;
  204.    return (operand);
  205. }
  206.      
  207.  
  208.  
  209.  
  210.  
  211.  
  212.            
  213.      
  214.      
  215.